﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

using StackExchange.Redis;

namespace Jack.RedisLib
{
    public interface IRedisClient : IDisposable
    {
        KeyValuePair<RedisKey, RedisValue>[] BatchConvertKeyValuesToRedisKeyValues<T>(Dictionary<string, T> keyValues);
        RedisValue[] BatchConvertObjectValueToRedisValue<T>(List<T> values);
        RedisKey[] BatchConvertStringKeyToRedisKey(List<string> keys);
        Task BatchExecute(Func<IBatch, Task> task, int db = -1, object asyncState = null, CancellationToken cancellationToken = default);
        RedisValue ConvertObjectValueToRedisValue<T>(T value);
        T ConvertRedisValueToObjectValue<T>(RedisValue redisValue) where T : class;
        T? ConvertRedisValueToValueTypeValue<T>(RedisValue redisValue) where T : struct;
        RedisKey ConvertStringKeyToRedisKey(string key);
        Task<bool> GeoAdd(string key, string member, double longitude, double latitude, int db = -1, CancellationToken cancellationToken = default);
        Task<long> GeoAdd(string key, List<(string Member, double Longitude, double Latitude)> geos, int db = -1, CancellationToken cancellationToken = default);
        Task<double?> GeoDistance(string key, string member1, string member2, GeoUnit geoUnit = GeoUnit.Meters, int db = -1, CancellationToken cancellationToken = default);
        Task<string> GeoHash(string key, string member, int db = -1, CancellationToken cancellationToken = default);
        Task<string[]> GeoHash(string key, List<string> members, int db = -1, CancellationToken cancellationToken = default);
        Task<(double Latitude, double Longitude)?> GeoPosition(string key, string member, int db = -1, CancellationToken cancellationToken = default);
        Task<(double Latitude, double Longitude)?[]> GeoPosition(string key, List<string> members, int db = -1, CancellationToken cancellationToken = default);
        Task<(string Member, double? Distance, long? Hash, double? Latitude, double? Longitude)[]> GeoRadius(string key, string member, double radius, GeoUnit unit = GeoUnit.Meters, int count = -1, Order? order = null, GeoRadiusOptions options = GeoRadiusOptions.Default, int db = -1, CancellationToken cancellationToken = default);
        Task<(string Member, double? Distance, long? Hash, double? Latitude, double? Longitude)[]> GeoRadius(string key, double longitude, double latitude, double radius, GeoUnit unit = GeoUnit.Meters, int count = -1, Order? order = null, GeoRadiusOptions options = GeoRadiusOptions.Default, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> GeoRemove(string key, string member, int db = -1, CancellationToken cancellationToken = default);
        Task<IDatabase> GetDatabase(int db = -1, CancellationToken cancellationToken = default);
        string GetKeyForInstance(string key);
        Task<string[]> GetSubscriptionChannels(CancellationToken cancellationToken = default);
        Task<long> GetSubscriptionPatternCount(CancellationToken cancellationToken = default);
        Task<long> GetSubscriptionSubscriberCount(string channel, CancellationToken cancellationToken = default);
        Task<long?> HashDecrement(string key, string hashField, long value = 1, int db = -1, CancellationToken cancellationToken = default);
        Task<double?> HashDecrement(string key, string hashField, double value, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> HashDelete(string key, string hashField, int db = -1, CancellationToken cancellationToken = default);
        Task<long> HashDelete(string key, List<string> hashFields, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> HashExists(string key, string hashField, int db = -1, CancellationToken cancellationToken = default);
        Task<T> HashGet<T>(string key, string hashField, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<Dictionary<string, T>> HashGet<T>(string key, List<string> hashFields, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<Dictionary<string, T>> HashGetAll<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<Dictionary<string, T?>> HashGetAllForValueType<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<T?> HashGetForValueType<T>(string key, string hashField, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<Dictionary<string, T?>> HashGetForValueType<T>(string key, List<string> hashFields, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<long?> HashIncrement(string key, string hashField, long value = 1, int db = -1, CancellationToken cancellationToken = default);
        Task<double?> HashIncrement(string key, string hashField, double value, int db = -1, CancellationToken cancellationToken = default);
        Task<string[]> HashKeys(string key, int db = -1, CancellationToken cancellationToken = default);
        Task<long> HashLength(string key, int db = -1, CancellationToken cancellationToken = default);
        Task<Dictionary<string, T?>> HashRandFieldForValueTypeWithValues<T>(string key, int count, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<List<string>> HashRandFieldWithoutValues<T>(string key, int count, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<Dictionary<string, T>> HashRandFieldWithValues<T>(string key, int count, int db = -1, CancellationToken cancellationToken = default) where T : class;
        IAsyncEnumerable<(string Field, T Value)> HashScan<T>(string key, string pattern = null, int pageSize = 250, long cursor = 0, int pageOffset = 0, int db = -1, CancellationToken cancellationToken = default) where T : class;
        IAsyncEnumerable<(string Field, T? Value)> HashScanForValueType<T>(string key, string pattern = null, int pageSize = 250, long cursor = 0, int pageOffset = 0, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<bool> HashSet<T>(string key, string hashField, T value, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> HashSet<T>(string key, Dictionary<string, T> hashFields, int db = -1, CancellationToken cancellationToken = default);
        Task<IGrouping<string, KeyValuePair<string, string>>[]> Info(string section = null, CancellationToken cancellationToken = default);
        Task<bool> KeyDelete(string key, int db = -1, CancellationToken cancellationToken = default);
        Task<long> KeyDelete(List<string> keys, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> KeyExists(string key, int db = -1, CancellationToken cancellationToken = default);
        Task<long> KeyExists(List<string> keys, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> KeyExpire(string key, TimeSpan? expiry, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> KeyExpire(string key, DateTime? expiry, int db = -1, CancellationToken cancellationToken = default);
        Task<TimeSpan?> KeyIdleTime(string key, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> KeyPersist(string key, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> KeyRename(string key, string newKey, int db = -1, CancellationToken cancellationToken = default);
        Task<TimeSpan?> KeyTimeToLive(string key, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> KeyTouch(string key, int db = -1, CancellationToken cancellationToken = default);
        Task<long> KeyTouch(List<string> keys, int db = -1, CancellationToken cancellationToken = default);
        Task<RedisType> KeyType(string key, int db = -1, CancellationToken cancellationToken = default);
        Task<T> ListGetByIndex<T>(string key, long index, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T?> ListGetByIndexForValueType<T>(string key, long index, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<long> ListInsertAfter<T>(string key, T pivot, T value, int db = -1, CancellationToken cancellationToken = default);
        Task<long> ListInsertBefore<T>(string key, T pivot, T value, int db = -1, CancellationToken cancellationToken = default);
        Task<T> ListLeftPop<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T[]> ListLeftPop<T>(string key, long count, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T?> ListLeftPopForValueType<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<T?[]> ListLeftPopForValueType<T>(string key, long count, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<long> ListLeftPush<T>(string key, T value, int db = -1, CancellationToken cancellationToken = default);
        Task<long> ListLeftPush<T>(string key, List<T> values, int db = -1, CancellationToken cancellationToken = default);
        Task<long> ListLength(string key, int db = -1, CancellationToken cancellationToken = default);
        Task<T[]> ListRange<T>(string key, long start = 0, long stop = -1, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T?[]> ListRangeForValueType<T>(string key, long start = 0, long stop = -1, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<long> ListRemove<T>(string key, T value, long count = 0, int db = -1, CancellationToken cancellationToken = default);
        Task<T> ListRightPop<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T[]> ListRightPop<T>(string key, long count, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T?> ListRightPopForValueType<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<T?[]> ListRightPopForValueType<T>(string key, long count, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<long> ListRightPush<T>(string key, T value, int db = -1, CancellationToken cancellationToken = default);
        Task<long> ListRightPush<T>(string key, List<T> values, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> ListSetByIndex<T>(string key, long index, T value, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> ListTrim<T>(string key, long start, long stop, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> LockWithExtend(string lockKey, TimeSpan expiry, Action job, string lockToken = null, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> LockWithExtend(string lockKey, TimeSpan expiry, Func<Task> job, string lockToken = null, int db = -1, CancellationToken cancellationToken = default);
        Task<long> Publish<T>(string channel, T message, RedisChannel.PatternMode mode = RedisChannel.PatternMode.Auto, int db = -1, CancellationToken cancellationToken = default);
        IAsyncEnumerable<string> ScanKeysForAllServer(string pattern = null, int pageSize = 250, long cursor = 0, int pageOffset = 0, int db = -1, CancellationToken cancellationToken = default);
        IAsyncEnumerable<string> ScanKeysForFirstServer(string pattern = null, int pageSize = 250, long cursor = 0, int pageOffset = 0, int db = -1, CancellationToken cancellationToken = default);
        IAsyncEnumerable<string> ScanKeysForSpecialServer(EndPoint endPoint, string pattern = null, int pageSize = 250, long cursor = 0, int pageOffset = 0, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> SetAdd<T>(string key, T value, int db = -1, CancellationToken cancellationToken = default);
        Task<long> SetAdd<T>(string key, List<T> values, int db = -1, CancellationToken cancellationToken = default);
        Task<T[]> SetCombine<T>(SetOperation operation, List<string> keys, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T?[]> SetCombineForValueType<T>(SetOperation operation, List<string> keys, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<bool> SetContains<T>(string key, T value, int db = -1, CancellationToken cancellationToken = default);
        Task<long> SetLength(string key, int db = -1, CancellationToken cancellationToken = default);
        Task<T[]> SetMembers<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T?[]> SetMembersForValueType<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<T> SetPop<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T[]> SetPop<T>(string key, long count, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T?> SetPopForValueType<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<T?[]> SetPopForValueType<T>(string key, long count, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<T> SetRandomMember<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T[]> SetRandomMember<T>(string key, long count, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T?> SetRandomMemberForValueType<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<T?[]> SetRandomMemberForValueType<T>(string key, long count, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<bool> SetRemove<T>(string key, T value, int db = -1, CancellationToken cancellationToken = default);
        Task<long> SetRemove<T>(string key, List<T> values, int db = -1, CancellationToken cancellationToken = default);
        IAsyncEnumerable<T> SetScan<T>(string key, string pattern = null, int pageSize = 250, long cursor = 0, int pageOffset = 0, int db = -1, CancellationToken cancellationToken = default) where T : class;
        IAsyncEnumerable<T?> SetScanForValueType<T>(string key, string pattern = null, int pageSize = 250, long cursor = 0, int pageOffset = 0, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<T[]> Sort<T>(string key, long skip = 0, long take = -1, Order order = Order.Ascending, SortType sortType = SortType.Numeric, string pattern = null, List<string> patterns = null, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<bool> SortedSetAdd<T>(string key, T member, double score, int db = -1, CancellationToken cancellationToken = default);
        Task<long> SortedSetAdd<T>(string key, Dictionary<T, double> members, int db = -1, CancellationToken cancellationToken = default);
        Task<double> SortedSetDecrement<T>(string key, T member, double value, int db = -1, CancellationToken cancellationToken = default);
        Task<double> SortedSetIncrement<T>(string key, T member, double value, int db = -1, CancellationToken cancellationToken = default);
        Task<long> SortedSetLength(string key, double min = double.NegativeInfinity, double max = double.PositiveInfinity, Exclude exclude = Exclude.None, int db = -1, CancellationToken cancellationToken = default);
        Task<long> SortedSetLengthByValue<T>(string key, T min, T max, Exclude exclude = Exclude.None, int db = -1, CancellationToken cancellationToken = default);
        Task<(T Element, double Score)?> SortedSetPop<T>(string key, Order order = Order.Ascending, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<Dictionary<T, double>> SortedSetPop<T>(string key, long count, Order order = Order.Ascending, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<(T? Element, double Score)?> SortedSetPopForValueType<T>(string key, Order order = Order.Ascending, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<Dictionary<T?, double>> SortedSetPopForValueType<T>(string key, long count, Order order = Order.Ascending, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<T[]> SortedSetRangeByRank<T>(string key, long start = 0, long stop = -1, Order order = Order.Ascending, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T?[]> SortedSetRangeByRankForValueType<T>(string key, long start = 0, long stop = -1, Order order = Order.Ascending, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<Dictionary<T, double>> SortedSetRangeByRankWithScores<T>(string key, long start = 0, long stop = -1, Order order = Order.Ascending, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<Dictionary<T?, double>> SortedSetRangeByRankWithScoresForValueType<T>(string key, long start = 0, long stop = -1, Order order = Order.Ascending, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<T[]> SortedSetRangeByScore<T>(string key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T?[]> SortedSetRangeByScoreForValueType<T>(string key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<T[]> SortedSetRangeByValue<T>(string key, T min = null, T max = null, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T?[]> SortedSetRangeByValueForValueType<T>(string key, T min = default, T max = default, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<long?> SortedSetRank<T>(string key, T member, Order order = Order.Ascending, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> SortedSetRemove<T>(string key, T member, int db = -1, CancellationToken cancellationToken = default);
        Task<long> SortedSetRemove<T>(string key, List<T> members, int db = -1, CancellationToken cancellationToken = default);
        Task<long> SortedSetRemoveRangeByRank(string key, long start, long stop, int db = -1, CancellationToken cancellationToken = default);
        Task<long> SortedSetRemoveRangeByScore(string key, double start, double stop, Exclude exclude = Exclude.None, int db = -1, CancellationToken cancellationToken = default);
        Task<long> SortedSetRemoveRangeByValue<T>(string key, T min, T max, Exclude exclude = Exclude.None, int db = -1, CancellationToken cancellationToken = default);
        IAsyncEnumerable<(T Element, double Score)> SortedSetScan<T>(string key, string pattern = null, int pageSize = 250, long cursor = 0, int pageOffset = 0, int db = -1, CancellationToken cancellationToken = default) where T : class;
        IAsyncEnumerable<(T? Element, double Score)> SortedSetScanForValueType<T>(string key, string pattern = null, int pageSize = 250, long cursor = 0, int pageOffset = 0, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<double?> SortedSetScore<T>(string key, T member, int db = -1, CancellationToken cancellationToken = default);
        Task<T?[]> SortForValueType<T>(string key, long skip = 0, long take = -1, Order order = Order.Ascending, SortType sortType = SortType.Numeric, string pattern = null, List<string> patterns = null, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<long> StreamAcknowledge(string key, string groupName, string messageId, int db = -1, CancellationToken cancellationToken = default);
        Task<long> StreamAcknowledge(string key, string groupName, List<string> messageIds, int db = -1, CancellationToken cancellationToken = default);
        Task<string> StreamAddAsync<T>(string key, string streamField, T streamValue, string messageId = null, int? maxLength = null, bool useApproximateMaxLength = false, int db = -1, CancellationToken cancellationToken = default);
        Task<string> StreamAddAsync<T>(string key, Dictionary<string, T> streamValues, string messageId = null, int? maxLength = null, bool useApproximateMaxLength = false, int db = -1, CancellationToken cancellationToken = default);
        Task<(string Id, Dictionary<string, T> Values)?[]> StreamClaim<T>(string key, string consumerGroup, string claimingConsumer, long minIdleTimeInMs, List<string> messageIds, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<(string Id, Dictionary<string, T?> Values)?[]> StreamClaimForValueType<T>(string key, string consumerGroup, string claimingConsumer, long minIdleTimeInMs, List<string> messageIds, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<string[]> StreamClaimIdsOnly(string key, string consumerGroup, string claimingConsumer, long minIdleTimeInMs, List<string> messageIds, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> StreamConsumerGroupSetPosition(string key, string groupName, string position, int db = -1, CancellationToken cancellationToken = default);
        Task<(string Name, int PendingMessageCount, long IdleTimeInMilliseconds)[]> StreamConsumerInfo(string key, string groupName, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> StreamCreateConsumerGroup(string key, string groupName, string position, bool createStream = true, int db = -1, CancellationToken cancellationToken = default);
        Task<long> StreamDelete(string key, List<string> messageIds, int db = -1, CancellationToken cancellationToken = default);
        Task<long> StreamDeleteConsumer(string key, string groupName, string consumerName, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> StreamDeleteConsumerGroup(string key, string groupName, int db = -1, CancellationToken cancellationToken = default);
        Task<(string Name, int ConsumerCount, int PendingMessageCount, string LastDeliveredId)[]> StreamGroupInfo(string key, int db = -1, CancellationToken cancellationToken = default);
        Task<StreamInfo> StreamInfo(string key, int db = -1, CancellationToken cancellationToken = default);
        Task<long> StreamLength(string key, int db = -1, CancellationToken cancellationToken = default);
        Task<StreamPendingInfo> StreamPending(string key, string groupName, int db = -1, CancellationToken cancellationToken = default);
        Task<StreamPendingMessageInfo[]> StreamPendingMessages(string key, string groupName, int count, string consumerName, string minId = null, string maxId = null, int db = -1, CancellationToken cancellationToken = default);
        Task<StreamEntry[]> StreamRange(string key, string minId = null, string maxId = null, int? count = null, Order messageOrder = Order.Ascending, int db = -1, CancellationToken cancellationToken = default);
        Task<StreamEntry[]> StreamRead(string key, string position, int? count = null, int db = -1, CancellationToken cancellationToken = default);
        Task<StreamEntry[]> StreamReadGroup(string key, string groupName, string consumerName, string position, int? count, bool noAck = false, int db = -1, CancellationToken cancellationToken = default);
        Task<long> StreamTrim(string key, int maxLength, bool useApproximateMaxLength = false, int db = -1, CancellationToken cancellationToken = default);
        Task<long?> StringDecrement(string key, long value = 1, int db = -1, CancellationToken cancellationToken = default);
        Task<double?> StringDecrement(string key, double value, int db = -1, CancellationToken cancellationToken = default);
        Task<T> StringGet<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<KeyValuePair<string, T>[]> StringGet<T>(List<string> keys, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T> StringGetDelete<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T?> StringGetDeleteForValueType<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<T?> StringGetForValueType<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<KeyValuePair<string, T?>[]> StringGetForValueType<T>(List<string> keys, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<T> StringGetSet<T>(string key, T newValue, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T> StringGetSetExpiry<T>(string key, TimeSpan? expiry = null, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T> StringGetSetExpiry<T>(string key, DateTime expiry, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T?> StringGetSetExpiryForValueType<T>(string key, TimeSpan? expiry = null, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<T?> StringGetSetExpiryForValueType<T>(string key, DateTime expiry, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<T?> StringGetSetForValueType<T>(string key, T newValue, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<(T Value, TimeSpan? Expiry)> StringGetWithExpiry<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<(T? Value, TimeSpan? Expiry)> StringGetWithExpiryForValueType<T>(string key, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task<long?> StringIncrement(string key, long value = 1, int db = -1, CancellationToken cancellationToken = default);
        Task<double?> StringIncrement(string key, double value, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> StringSet<T>(string key, T value, TimeSpan? expiry = null, int db = -1, CancellationToken cancellationToken = default);
        Task<bool> StringSet<T>(Dictionary<string, T> keyValues, int db = -1, CancellationToken cancellationToken = default);
        Task<T> StringSetAndGet<T>(string key, T value, TimeSpan? expiry = null, int db = -1, CancellationToken cancellationToken = default) where T : class;
        Task<T?> StringSetAndGetForValueType<T>(string key, T value, TimeSpan? expiry = null, int db = -1, CancellationToken cancellationToken = default) where T : struct;
        Task SubScribe<T>(string channel, Action<T> messageHandler, RedisChannel.PatternMode mode = RedisChannel.PatternMode.Auto, object asyncState = null, CancellationToken cancellationToken = default) where T : class;
        Task<(bool ExecuteResult, Exception Exception)> TransactionExecute(Func<ITransaction, Task> task, int db = -1, object asyncState = null, CancellationToken cancellationToken = default);
        Task UnsubscribeAll(object asyncState = null, CancellationToken cancellationToken = default);
    }
}
